package darknet.core.impl.net;

import darknet.application.base.spec.BaseApplication;
import darknet.core.spec.net.NetworkManager;
import darknet.core.spec.net.Node;
import darknet.core.spec.net.Protocol;
import darknet.core.spec.net.ProtocolHandler;
import darknet.core.spec.net.ProtocolSender;
import java.io.IOException;
import java.util.Set;

/**
 * Base application (ping).
 *
 * @author Yoyo
 */
class BaseApplicationImpl implements BaseApplication {

    /** The network manager. */
    private NetworkManager networkManager;

    /** The base protocol. */
    private BaseProtocol protocol;

    /** The base protocol handler */
    private BaseProtocolHandler handler;

    /** The base protocol sender */
    private BaseProtocolSender sender;

    /**
     * Initialise a new base application.
     * 
     * @param networkManager
     */
    BaseApplicationImpl(NetworkManager networkManager) {

        if (networkManager == null) {
            throw new IllegalArgumentException("networkManager is null");
        }
        this.networkManager = networkManager;

        this.protocol = BaseProtocol.getCurrent();
        this.handler = new BaseProtocolHandler(this);
	this.sender = new BaseProtocolSender(this);
    }

    @Override
    public Long ping(String nodeName) throws IOException {

        PingMessage message = BaseMessageFactory
                .getInstance(networkManager)
                .makePingMessage(networkManager.getNode(nodeName));

        Long begin = System.currentTimeMillis();
        networkManager.send(message);
        Long end = System.currentTimeMillis();

        return end - begin;
    }

    @Override
    public Protocol getProtocol() {
        return protocol;
    }

    @Override
    public ProtocolHandler getHandler() {
        return handler;
    }

    @Override
    public ProtocolSender getSender() {
        return sender;
    }

    @Override
    public Set<Node> getReachableNodes() {
        // TODO Write this method.
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public NetworkManager getNetworkManager() {
        return networkManager;
    }
}
